package asem.ast.expresiones;

import java.util.LinkedList;

import alex.Token;
import asem.TablaSimbolos;
import asem.excepciones.ExcepcionClaseInexistente;
import asem.excepciones.ExcepcionSignaturaIncorrecta;
import asem.tablaSimbolos.Clase;
import asem.tablaSimbolos.Constructor;
import asem.tablaSimbolos.Parametro;
import asem.tablaSimbolos.tipo.Tipo;
import asem.tablaSimbolos.tipo.TipoClase;
import asem.tablaSimbolos.tipo.TipoMetodo;

public class NodoNuevoObjeto extends NodoPrimario {
	protected Token identificador;
	protected LinkedList<NodoExpresion> argsActuales;
	protected NodoLlamadaEncadenada cadenaId;

	public NodoNuevoObjeto(Token token, LinkedList<NodoExpresion> args,
			NodoLlamadaEncadenada lista) {
		identificador = token;
		argsActuales = args;
		cadenaId = lista;
	}

	@Override
	public TipoMetodo chequeoSentencias() {
		Clase c = TablaSimbolos.tabla.getClase(identificador.getLexema());
		if (c == null)
			throw new ExcepcionClaseInexistente(identificador);

		chequeoArgs(c.getConstructor());
		TipoMetodo retorno = new TipoClase(c.getIdentificador());

		if (cadenaId != null)
			retorno = cadenaId.chequeoSentencias((Tipo) retorno);

		return retorno;
	}

	private void chequeoArgs(Constructor met) {
		Tipo t;
		Parametro p;
		int i = 1;
		int f = met.getCantParametros();

		for (NodoExpresion exp : argsActuales) {
			if (i > f)
				throw new ExcepcionSignaturaIncorrecta(met.getIdentificador());

			t = (Tipo) exp.chequeoSentencias();
			p = met.obtenerParametroPosicion(i);

			if (p.getTipo().compatible(t))
				throw new ExcepcionSignaturaIncorrecta(met.getIdentificador(),
						p, t);

			i++;
		}

		if (i != f)
			throw new ExcepcionSignaturaIncorrecta(met.getIdentificador());

	}
}
